package com.fingard.dsp.bank.directbank.gfgs01;

import org.apache.axis.client.Call;
import org.apache.axis.client.Service;
import org.apache.axis.encoding.XMLType;

import com.fingard.FGBiz;
import com.fingard.constant.Format;
import com.fingard.dsp.bank.directConfig.FtpSet;
import com.fingard.dsp.bank.directbank.DirectBase;
import com.fingard.net.*;
import com.fingard.util.TransIDHelper;
import com.fingard.xml.XmlTextReader;
import com.fingard.xml.XmlTextWriter;

import javax.xml.rpc.ParameterMode;

import java.io.File;
import java.util.Date;

/**
 * Created by F on 2018/11/26.
 * 公共方法
 */
public class GFGS01Base extends DirectBase implements ITcpClient {

    private static TransIDHelper idHelper = new TransIDHelper(0, 9);

    @Override
    public void getContentLength(TcpReceiver p_receiver) throws Exception {
        if (p_receiver.contentLength == -1) {
            String tmpCharset = getCharset();
            String tmpRecNow = new String(p_receiver.recBytes, 0, p_receiver.readedLength, tmpCharset);
            if (tmpRecNow.contains("<ufinterface>")) {
                p_receiver.contentLength = p_receiver.readedLength;
                p_receiver.contentStartIndex = 0;
            }
        }
    }

    /**
     * 编码
     * @return
     */
    protected String getCharset(){
        return getBankConfig().getCharset("UTF-8");
    }

    /**
     * 编码
     * @return
     */
    protected String getCharset2(){
        return "gbk";
    }

    /**
     *  请求报文头
     * @param xmlWriter
     * @param p_bankHeader
     * @throws Exception
     */
    protected void writeCommonHeader(XmlTextWriter xmlWriter, GFGS01Header p_bankHeader) throws Exception{
        xmlWriter.writeStartDocByDeclaration("<?xml version=\"1.0\" encoding = \"utf-8\"?>");
        xmlWriter.writeElementAttribute("ufinterface","roottag",
                ""+p_bankHeader.roottag+"\" billtype=\""+p_bankHeader.billType+"\" replace=\"Y\" receiver=\"1001\" " +
                        "sender=\"GFGS\" isexchange=\"Y\" proc=\"add\" operation=\"req");
    }

    /**
     * 需生成签名格式报文的原文
     * @param p_original
     * @return
     * @throws Exception
     */
    private String generateSignPlain(String p_original) throws Exception {
        WriteBankLogLn2("需要签名的数据包的原文为：" + p_original);
        StringBuilder sb = new StringBuilder();
        sb.append("POST HTTP://"+bankFront.serverIP+"/servlet/ABC95599.Trans HTTP/1.0\r\n");
        sb.append("Accept:image/gif, image/x-xbitmap, image/jpeg, image/pjpeg,\r\n");
        sb.append("application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*\r\n");
        sb.append("Referer: HTTP://"+bankFront.serverIP+"/personRACrtLY.htm\r\n");
        sb.append("Accept-Language: zh-cn\r\n");
        sb.append("Content-Type: INFOSEC_SIGN/1.0\r\n");
        sb.append("Proxy-Connection: Keep-Alive\r\n");
        sb.append("User-Agent: Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)\r\n");
        sb.append("Host: "+bankFront.serverIP+"\r\n");
        sb.append("Content-Length: "+String.valueOf(p_original.trim().getBytes().length)+"\r\n");
        sb.append("Pragma: no-cache\r\n");
        sb.append(p_original.trim());
        return sb.toString();
    }

    /**
     * 签名
     * @param p_reqStr
     * @param p_sb
     * @return
     */
    protected boolean getSignedData(String p_reqStr, StringBuilder p_sb) throws Exception{
        String[] retStr=new String[]{"",""};
        try {
            String p_signPlain = p_reqStr;
            WriteBankLogLn("提交银行进行签名的报文为：" + p_signPlain);
            String url = "http://"+ bankFront.serverIP + ":" + bankFront.signPort + "/servlet/ABC95599.Trans";
            WriteBankLogLn("进行签名的地址为：" + url);
            WebRequest tmpWebRequest = new WebRequest(url);
            tmpWebRequest.setConnectTimeout(60000);
            tmpWebRequest.setRequestProperty("Accept","image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, " +
                    "application/vnd.ms-powerpoint, application/vnd.ms-excel, application/msword, */*");
            tmpWebRequest.setRequestProperty("Referer","http://"+bankFront.serverIP+"/personRACrtLY.htm");
            tmpWebRequest.setRequestProperty("Accept-Language","zh-cn");
            tmpWebRequest.setRequestProperty("Content-Type","INFOSEC_SIGN/1.0");
            tmpWebRequest.setRequestProperty("Proxy-Connection", "Keep-Alive");
            tmpWebRequest.setRequestProperty("User-Agent", " Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.0)");
            String charsetName = getCharset();
            byte[] tmpToWriteBytes = p_signPlain.getBytes(charsetName);
            retStr = tmpWebRequest.upload(tmpToWriteBytes, charsetName);

            if(retStr[0].length()==0){
                WriteBankLogLn("签名返回报文：" + retStr[1]);
                XmlTextReader tmpBkReader = loadBankRespXmlReader(retStr[1], p_sb);
                if (tmpBkReader != null) {
                    if (tmpBkReader.read("/html/body/sign")) {
                        p_sb.append(tmpBkReader.readedXElement.innerText.replace("\r", "").replace("\n", ""));
                        return true;
                    } else {
                        if (tmpBkReader.read("/html/head/result")) {
                            p_sb.append(String.format("签名失败，返回错误码：%s", tmpBkReader.readedXElement.innerText));
                        } else {
                            p_sb.append("签名失败，银行未返回错误码！");
                        }
                    }
                }
            }
        } catch (Exception ex) {
            p_sb.append(ex.getMessage());
        }
        return false;
    }

    /**
     * 发送报文至银行
     * @param p_reqStr 请求报文
     * @return
     * @throws Exception
     */
    protected String[] sendToBank(String p_reqStr,GFGS01Header header) throws Exception {
        String[] retStr = new String[]{"", ""};
        WriteBankLogLn("1.提交银行的地址：" + bankFront.serverURL);
        String xml=p_reqStr;
        WriteBankLogStep2(xml);
        Service service=new Service();
        Call call = (Call) service.createCall();
        call.setTargetEndpointAddress(bankFront.serverURL);// 远程调用路径
        call.setOperationName(header.wsdlMethod);// 调用的方法名
        // 设置参数名: 参数名,参数类型,参数模式
        call.addParameter("xml", XMLType.XSD_STRING, ParameterMode.IN);
        call.setReturnType(XMLType.XSD_STRING);// 设置被调用方法的返回值类型
        String returnData = (String) call.invoke(new Object[] { xml });// 远程调用
        if(returnData.contains("<ufinterface isexchange='Y' proc='' roottag='sendresult'>")){
            retStr[0]="";
            retStr[1]=returnData;
        }else {
            retStr[0]="E9999";
            retStr[1]=returnData;
        }
        WriteBankLogStep3(retStr[1]);
        return retStr;
    }

    protected static boolean isActiveRetCode(String retCode) {
        if (retCode != null) {
            if (retCode.equals("0")) {
                return true;
            }
        }
        return false;
    }

    protected String getQryTransID() {
        Date tmpDateNow = new Date();
        return "WL"+Format.DateTime17Format.format(tmpDateNow) + idHelper.getNextIDStr();
    }

    protected String getBankType(String recBankName) throws Exception{
        String bankType="";
        if(!"".equals(recBankName) && recBankName!=null){
            if(recBankName.contains("工商银行")){
                bankType="01";
            }else if(recBankName.contains("招商银行")){
                bankType="02";
            }else if(recBankName.contains("中国人民银行")){
                bankType="03";
            }else if(recBankName.contains("建设银行")){
                bankType="04";
            }else if(recBankName.contains("深圳发展银行")){
                bankType="05";
            }else if(recBankName.contains("光大银行")){
                bankType="06";
            }else if(recBankName.contains("农业银行")){
                bankType="07";
            }else if(recBankName.contains("中国银行")){
                bankType="08";
            }else if(recBankName.contains("浦发银行")){
                bankType="09";
            }else if(recBankName.contains("交通银行")){
                bankType="10";
            }else if(recBankName.contains("民生银行")){
                bankType="11";
            }else if(recBankName.contains("华夏银行")){
                bankType="12";
            }else if(recBankName.contains("兴业银行")){
                bankType="13";
            }else if(recBankName.contains("天津银行")){
                bankType="14";
            }else if(recBankName.contains("广发银行")){
                bankType="15";
            }else if(recBankName.contains("北京银行")){
                bankType="16";
            }else if(recBankName.contains("北京农村商业银行")){
                bankType="17";
            }else if(recBankName.contains("国家开发银行")){
                bankType="18";
            }else if(recBankName.contains("中信银行")){
                bankType="19";
            }else if(recBankName.contains("香港汇丰银行")){
                bankType="20";
            }else if(recBankName.contains("中国电力财务公司")){
                bankType="21";
            }else if(recBankName.contains("日本三菱银行")){
                bankType="22";
            }else if(recBankName.contains("花旗银行")){
                bankType="23";
            }else if(recBankName.contains("上海银行")){
                bankType="24";
            }else if(recBankName.contains("深圳平安银行")){
                bankType="25";
            }else if(recBankName.contains("中国邮政储蓄银行")){
                bankType="26";
            }else if(recBankName.contains("徽商银行")){
                bankType="27";
            }else if(recBankName.contains("北京高华证券")){
                bankType="28";
            }else if(recBankName.contains("东方证券")){
                bankType="29";
            }else if(recBankName.contains("国泰君安证券")){
                bankType="30";
            }else if(recBankName.contains("上海农商银行")){
                bankType="31";
            }else if(recBankName.contains("兴业证券")){
                bankType="32";
            }else if(recBankName.contains("中国国际金融有限公司")){
                bankType="33";
            }else if(recBankName.contains("中信建投证券")){
                bankType="34";
            }else if(recBankName.contains("渣打银行")){
                bankType="35";
            }else if(recBankName.contains("中国农业发展银行")){
                bankType="36";
            }else if(recBankName.contains("农村信用社")){
                bankType="37";
            }else if(recBankName.contains("农村商业银行")){
                bankType="38";
            }else if(recBankName.contains("农村合作银行")){
                bankType="39";
            }else if(recBankName.contains("浙商银行")){
                bankType="40";
            }else if(recBankName.contains("南京银行")){
                bankType="41";
            }else if(recBankName.contains("法国兴业银行")){
                bankType="42";
            }else if(recBankName.contains("国家金库")){
                bankType="98";
            }else{//它行
                bankType="99";
            }
        }
        if("".equals(bankType)){
            throw new Exception("收款人开户行名为空");
        }
        return bankType;
    }

    protected void downFromFtp(String localReceiptPath, FtpSet ftpSet, String fileName,String date)  throws Exception {
        FtpPortClient ftpPtClient = new FtpPortClient(ftpSet);
        //从FTP下载回单
        FtpReceiver ftpReceiver = null;
        try {
            ftpPtClient.setLocalPassiveMode();
            ftpPtClient.connect();
            ftpPtClient.list(ftpSet.downDir+"/"+date+"/", false);
            WriteBankLogLn("开始从【" + ftpSet.serverIP + ":" + ftpSet.port + ftpSet.downDir+"/"+date + "】下载回单文件");
            if (ftpPtClient.arFiles.size() > 0) {
                for (String receiptZip : ftpPtClient.arFiles) {
                    if(receiptZip.contains(fileName)) {
                        ftpReceiver = ftpPtClient.downloadFile(receiptZip, localReceiptPath + File.separator + receiptZip.substring(receiptZip.lastIndexOf("/") + 1));
                        if (ftpReceiver.isCompleted) {
                            WriteBankLogLn("成功下载回单文件:" + receiptZip + "至" + localReceiptPath);
                        } else {
                            WriteBankLogLn(receiptZip + "回单文件下载失败:" + ftpReceiver.connMsg + "+" + ftpReceiver.connState);
                        }
                    }
                }
            } else {
                WriteBankLogLn("【" + ftpSet.serverIP + ":" + ftpSet.port + ftpSet.downDir + "】不存在文件");
            }
        } finally {
            ftpPtClient.disconnect();
        }

    }

    /**
     * 获取账号指定日期的明细流水号
     * @param actNum：账号
     * @param date：查询日期
     * @return
     * @throws Exception
     */
    protected String selectReceipt(String actNum,String date) throws Exception{
        StringBuilder stringBuilder = new StringBuilder();//记录流水号
        //非公有参数
        XmlTextWriter xmlTextWriter = new XmlTextWriter();
        //拼接请求报文头
        GFGS01Header header=new GFGS01Header();
        header.billType="detailquery";//交易码
        header.roottag="query";
        header.wsdlMethod="queryHisDetail";//提供webservice接口，查询当日交易明细
        writeCommonHeader(xmlTextWriter,header);
        //拼接请求报文体
        xmlTextWriter.writeStartElement("query");
        xmlTextWriter.writeElementString("acc",actNum);//帐号
        xmlTextWriter.writeElementString("begindate", date.substring(0,4)+"-"+date.substring(4,6)+"-"+date.substring(6));//开始时间
        xmlTextWriter.writeElementString("enddate", date.substring(0,4)+"-"+date.substring(4,6)+"-"+date.substring(6));//结束时间
        xmlTextWriter.writeEndElement();
        xmlTextWriter.writeEndDocument();
        //发送请求报文
        String[] resutlt = sendToBank(xmlTextWriter.toXmlString(),header);

        //测试
        //WriteBankLogStep2(xmlTextWriter.toXmlString());
        //String[] resutlt=new String[]{"","<?xml version='1.0' encoding='gb2312'?><ufinterface isexchange='Y' proc='' roottag='sendresult'>    <sendresult>        <acc>2120135301</acc>        <retcode>0</retcode>        <retmemo>成功</retmemo>        <detail>            <row>                <transdate>2019-03-28</transdate>                <payamt>488</payamt>                <getamt></getamt>                <opacc>6212263002004941137</opacc>                <opname>员军民</opname>                <usage>赵鸽/业务招待费-宴请乌鲁木齐机场配载平衡</usage>                <retsourcebusino>35G020190328195117</retsourcebusino>                <vdef18></vdef18>                <vdef19>WL201903281613159210</vdef19>            </row>            <row>                <transdate>2019-03-28</transdate>                <payamt>1080</payamt>                <getamt></getamt>                <opacc>6222022703008122969</opacc>                <opname>李颉</opname>                <usage>赵鸽/物流兰州分公司人员请股份教员蒋卫红</usage>                <retsourcebusino>35G020190328195118</retsourcebusino>                <vdef18></vdef18>                <vdef19>WL201903281612287679</vdef19>            </row>        </detail>    </sendresult></ufinterface>\n"};
        //WriteBankLogStep3(resutlt[1]);

        //处理响应报文
        if(resutlt[0].length()==0){
            StringBuilder tmpSbMsg = new StringBuilder();
            XmlTextReader tmpBkReader = loadBankRespXmlReader(resutlt[1].trim(),tmpSbMsg);
            if(tmpBkReader!=null) {
                String respCode = tmpBkReader.getFirstText("/ufinterface/sendresult/retcode");
                if("".equals(respCode) || respCode==null){//查询明细成功，且为空

                }else if(isActiveRetCode(respCode)) { //查询明细成功，且不为空
                    //明细流水号|交易额|交易方向|对方账号|对方户名|
                    while (tmpBkReader.read("/ufinterface/sendresult/detail/row")) {
                        stringBuilder.append(tmpBkReader.readedXElement.getSingleTextNotNull("retsourcebusino").trim()).append("|");
                        String payamt = tmpBkReader.readedXElement.getSingleTextNotNull("payamt").trim();//支出金额
                        String getamt = tmpBkReader.readedXElement.getSingleTextNotNull("getamt").trim();//收入金额
                        String cdFlag="";//交易方向
                        String tranAmt="";//交易额
                        if (!"".equals(payamt) && payamt!=null) {
                            if (payamt.indexOf("-") > 0) {
                                cdFlag = "2";//贷
                                tranAmt = payamt.substring(1);//交易金额
                            } else {
                                cdFlag = "1";//借
                                tranAmt = payamt;//交易金额
                            }
                        } else if (!"".equals(getamt) && getamt!=null) {
                            if (payamt.indexOf("-") > 0) {
                                cdFlag = "1";//借
                                tranAmt = getamt.substring(1);//交易金额
                            } else {
                                cdFlag = "2";//贷
                                tranAmt = getamt;//交易金额
                            }
                        }
                        stringBuilder.append(tranAmt).append("|");
                        stringBuilder.append(cdFlag).append("|");
                        stringBuilder.append(tmpBkReader.readedXElement.getSingleTextNotNull("opacc").trim()).append("|");
                        stringBuilder.append(tmpBkReader.readedXElement.getSingleTextNotNull("opname").trim()).append("|");
                        stringBuilder.append("#");
                    }
                }
            }
        }
        WriteBankLogLn("查询到的明细流水为"+stringBuilder.toString());
        return stringBuilder.toString();
    }

    //上送格式为json格式
    protected  String[] sendToATS(String jsonData) throws Exception{
        String[] retStr = new String[]{"",""};
        WriteBankLogLn("2.提交ATS的地址："+ FGBiz.dspCenter.dspSet.receiptPushServerUrl);

        //发送ATS
        WebRequest tmpRequest = new WebRequest(FGBiz.dspCenter.dspSet.receiptPushServerUrl);
        tmpRequest.setConnectTimeout(60000);
        tmpRequest.setRequestProperty("connection", "Close");
        tmpRequest.setRequestProperty("Content-Type","application/x-www-form-urlencoded");
        String charsetName = getCharset2();
        WriteBankLogLn("3.推送给ATS的json数据"+jsonData);
        byte[] tmpWriteBytes = jsonData.getBytes(charsetName);
        retStr = tmpRequest.upload(tmpWriteBytes, charsetName);
        WriteBankLogLn("4.返回的数据"+retStr[1]);

        return retStr;
    }
}
